/*
 * vim:foldmethod=marker:
 */
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <assert.h>
#include <limits.h>
#include <ctype.h>

/*
#ifdef D
# error "wtf is D?"
#else
# define D
#endif
 */

/* {{{ mergesort */
static void
mergesort__merge(void *pbase, size_t nmemb, size_t size,
		int (*cmpf)(const void *, const void *),
		void *pcpybuf,
		size_t L, size_t M, size_t R)
{
	register char *base = (char *) pbase,
		      *cpybuf = (char *) pcpybuf;
	register size_t i = L,
			j = M + 1,
			s = 0; /* index
				  points to where we will place next element */

#ifdef D
	fprintf(stderr, "mergesort__merge(pbase==%p, nmemb==%zu, size==%zu, cmpf==%p, pcpybuf==%p, L==%zu, M==%zu, R==%zu)\n",
			pbase, nmemb, size, cmpf, pcpybuf, L, M, R);
#endif

	while (i <= M && j <= R) { //so this || was working great for almost a year… until now
#ifdef D
		fprintf(stderr, "mergesort__merge: calling (*cmpf)((void *) (base + i * size) == %016p, "
				"(void *) (base + j * size) == %016p) //i==%zu, j==%zu\n",
				(void *) (base + i * size), (void *) (base + j * size),
				i, j);
#endif
		if ((*cmpf)((void*) (base + i * size), (void*) (base + j * size)) <= 0) { //HOLD UP!.. nah nvm
			if (i <= M) {
				memcpy((void *) (cpybuf + s * size),
					(void *) (base + i * size), size);
				s++;
				i++;
			} else if (j <= R) {
				memcpy((void *) (cpybuf + s * size),
					(void *) (base + j * size), size);
				s++;
				j++;
			}
		} else {
			if (j <= R) {
				memcpy((void *) (cpybuf + s * size),
					(void *) (base + j * size), size);
				s++;
				j++;
			} else if (i <= M) {
				memcpy((void *) (cpybuf + s * size),
					(void *) (base + i * size), size);
				s++;
				i++;
			}
		}
	}

	/*
	 * let's see how this works
	 */
	while (i <= M)
		memcpy((void*) (cpybuf + (s++) * size),
			(void*) (base + (i++) * size), size);
	while (j <= R)
		memcpy((void*) (cpybuf + (s++) * size),
			(void*) (base + (j++) * size), size);

	for (i = 0; i < s; i++)
		memcpy((void *) (base + (L + i) * size),
				(void *) (cpybuf + i * size), size);
}

static void
mergesort__main(void *base, size_t nmemb, size_t size,
		int (*cmpf)(const void *, const void *),
		void *cpybuf,
		size_t L, size_t R)
{
	size_t M = (L + R) / 2;

	if (L < R) {
		mergesort__main(base, nmemb, size, cmpf, cpybuf, L, M);
		mergesort__main(base, nmemb, size, cmpf, cpybuf, M + 1, R);
		mergesort__merge(base, nmemb, size, cmpf, cpybuf, L, M, R);
	}
}

extern void
mergesort(void *base, size_t nmemb, size_t size,
		int (*cmpf)(const void *, const void *))
{
	void *cpybuf = NULL;

	cpybuf = malloc(nmemb * size + 1UL);
	mergesort__main(base, nmemb, size, cmpf, cpybuf,
			0UL, nmemb - 1UL);
	free(cpybuf);
}
/* }}} */

/* {{{ bsearch */
extern void *
bsearch(const void *key, const void *pbase, size_t nmemb, size_t size,
		int (*cmpf)(const void *, const void *))
{
	const char *base = (const char *) pbase;
	size_t left = 0,
	       right = nmemb,
	       mid;
	register int cmpres;

	while (left < right) {
		mid = (left + right) / 2;
		cmpres = (*cmpf)(key, (void *) (base + mid * size));
		if (cmpres > 0)
			left = mid + 1;
		else if (cmpres < 0)
			right = mid;
		else
			return (void *) (base + mid * size);
	}

	return NULL;
}
/* }}} */

int
cmpstrp(const void *p1, const void *p2)
{
#ifdef D
	fprintf(stderr, "p1 == \"%s\", p2 == \"%s\"\n",
			* (const char * const *) p1, * (const char * const *) p2);
#endif
	return strcmp(* (const char * const *) p1, * (const char * const *) p2);
}

int
main(int argc, char **argv)
{
	char **first, **second, **merged;
	char word[32];
	int n, m, i, j;

	scanf("%d", &n);
	first = malloc(n * sizeof *first);
	for (i = 0; i < n; i++) {
		scanf("%s", word);
		first[i] = strdup(word);
	}
	mergesort(first, (size_t) n, sizeof first[0], cmpstrp);

	scanf("%d", &m);
	second = malloc(m * sizeof *second);
	for (i = j = 0; i < m; i++) {
		scanf("%s", word);
		second[i] = strdup(word);
	}
	mergesort(second, (size_t) m, sizeof *second, cmpstrp);

	merged = malloc(((size_t) n + m) * sizeof *merged);
	for (i = 0; i < n; i++)
		merged[i] = first[i];
	for (; i - n < m; i++)
		merged[i] = second[i - n];
	mergesort(merged, (size_t) n + m, sizeof *merged, cmpstrp);

	printf("%s\n", merged[0]);
	for (i = 1; i < n + m; i++) {
		if (strcmp(merged[i], merged[i - 1]) != 0)
			printf("%s\n", merged[i]);
	}

	for (i = 0; i < n; i++) free(first[i]);
	for (i = 0; i < m; i++) free(second[i]);
	free(first);
	free(second);
	free(merged);
	return 0;
}
